/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */
import { defineBoot } from '#q-app/wrappers'
import axios, { type AxiosInstance } from 'axios'
import { isAuthenticated, getUserInfo, removeUserInfo } from '@/utils'
import { useUserStore } from '@/stores/user-store'

declare module 'vue' {
  interface ComponentCustomProperties {
    $axios: AxiosInstance
    $api: AxiosInstance
  }
}

// Be careful when using SSR for cross-request state pollution
// due to creating a Singleton instance here;
// If any client changes this (global) instance, it might be a
// good idea to move this instance creation inside of the
// "export default () => {}" function below (which runs individually
// for each client)
const api = axios.create({
  baseURL: 'http://47.115.213.19'
})

// Add a request interceptor
api.interceptors.request.use(
  function (config) {
    // Do something before request is sent
    const method = (config.method as string).toLowerCase()
    if (method !== 'get') {
      config.headers['Content-Type'] = 'application/json'
    }
    const url = config.url || ''
    const isNoNeedToken = url.includes('/survey-form') || url.includes('/auth')
    if (!isNoNeedToken && isAuthenticated()) {
      const oUser = getUserInfo() as IUser
      config.headers['Authorization'] = `Bearer ${oUser.accessToken}`
    }
    return config
  },
  function (error) {
    // Do something with request error
    return Promise.reject(error)
  }
)
const { setUser } = useUserStore()
function reLogin() {
  setUser()
  removeUserInfo()
  const { origin, href } = location
  if (!href.includes('/login')) {
    location.href = `${origin}/#/login?redirect=${encodeURIComponent(href)}`
  }
}
// Add a response interceptor
api.interceptors.response.use(
  function (res) {
    const hasStatus = res && res.data && res.data.code
    if (hasStatus) {
      const code = res.data.code
      if (code === 401) {
        reLogin()
      }
    }
    return res
  },
  function (error) {
    return Promise.reject(error)
  }
)

export default defineBoot(({ app }) => {
  // for use inside Vue files (Options API) through this.$axios and this.$api

  app.config.globalProperties.$axios = axios
  // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form)
  //       so you won't necessarily have to import axios in each vue file

  app.config.globalProperties.$api = api
  // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form)
  //       so you can easily perform requests against your app's API
})

export { api }
